package log

import (
	"fmt"
	"io"
	"os"
	"path"
	"time"

	"github.com/cloudwego/hertz/pkg/common/hlog"
	hertzzap "github.com/hertz-contrib/logger/zap"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

func Init(logDir string, logLevel string) bool {
	// 1. 设置日志文件路径
	var logFilePath = logDir
	if err := os.MkdirAll(logDir, 0o777); err != nil {
		hlog.Error(err)
		return false
	}
	PrePrintf("设置日志文件路径为:%v", logFilePath)

	// 设置日志文件名
	logFileName := time.Now().Format("2006-01-02") + ".log"
	fileName := path.Join(logFilePath, logFileName)
	if _, err := os.Stat(fileName); err != nil {
		if _, err := os.Create(fileName); err != nil {
			hlog.Error(err)
			return false
		}
	}
	PrePrintf("设置日志文件名称为:%v", logFileName)
	PrePrintf("设置日志文件名称为:%v", fileName)
	//hlog.FormatLogger.

	// 获取日志等级
	var lv hlog.Level
	switch logLevel {
	case "Trace":
		lv = hlog.LevelTrace
	case "Debug":
		lv = hlog.LevelDebug
	case "Info":
		lv = hlog.LevelInfo
	case "Notice":
		lv = hlog.LevelNotice
	case "Warn":
		lv = hlog.LevelWarn
	case "Error":
		lv = hlog.LevelError
	case "Fatal":
		lv = hlog.LevelFatal
	default:
		hlog.Errorf("无效的日志级别,%v", logLevel)
		return false
	}
	PrePrintf("设置日志等级为:%v", logLevel)

	// 初始化zap日志对象

	logger := hertzzap.NewLogger(
		hertzzap.WithCores(*defaultCoreConfig()),
		hertzzap.WithZapOptions(zap.WithCaller(lv < hlog.LevelInfo), zap.AddCallerSkip(3)),
		hertzzap.WithExtraKeys([]hertzzap.ExtraKey{"reqid"}), // 指定要包含在日志中的额外键
		hertzzap.WithExtraKeyAsStr(),                         // 指定 extraKeys 中的键是字符串
	)
	// Provides compression and deletion
	lumberjackLogger := &lumberjack.Logger{
		Filename:   fileName,
		MaxSize:    20,   // A file can be up to 20M.
		MaxBackups: 5,    // Save up to 5 files at the same time.
		MaxAge:     10,   // A file can exist for a maximum of 10 days.
		Compress:   true, // Compress with gzip.
	}

	logger.SetOutput(lumberjackLogger)
	logger.SetLevel(lv)
	// if you want to output the log to the file and the stdout at the same time, you can use the following codes

	fileWriter := io.MultiWriter(lumberjackLogger, os.Stdout)
	logger.SetOutput(fileWriter)

	hlog.SetLogger(logger)
	return true
}

func defaultCoreConfig() *hertzzap.CoreConfig {
	customTimeFormat := "2006-01-02 15:04:05.000"
	// default log encoder
	enc := zapcore.NewJSONEncoder(zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		FunctionKey:    zapcore.OmitKey,
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.TimeEncoderOfLayout(customTimeFormat),
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	})
	// default log level
	lvl := zap.NewAtomicLevelAt(zap.InfoLevel)
	// default write syncer stdout
	ws := zapcore.AddSync(os.Stdout)

	return &hertzzap.CoreConfig{
		Enc: enc,
		Ws:  ws,
		Lvl: lvl,
	}
}

func PrePrintf(format string, a ...interface{}) {
	// 获取当前时间
	now := time.Now()
	// 格式化日期时间为指定格式，例如：2006-01-02 15:04:05
	dateTime := now.Format("2006-01-02 15:04:05")
	// 使用fmt.Printf输出日期时间，然后是一个制表符，最后是原始消息
	fmt.Printf(dateTime+"\t"+format+"\n", a...)
}
